#include<iostream>
#include<thread>

using namespace std;

////try
////{
////	// 保护的标识代码
////}
////catch (ExceptionName e1)
////{
////	// catch 块
////}
////catch (ExceptionName e2)
////{
////	// catch 块
////}
////catch (ExceptionName eN)
////{
////	// catch 块
////}
//
//int main()
//{
//	
//	//就会调用构造函数
//	return 0;
//}
//
//double Division(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Division by zero condition!";
//	}
//	return (double)a / (double)b;
//}
//void Func()
//{
//	int* array = new int[10]; //申请空间
//	try 
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Division(len, time) << endl;// 这里如果抛异常，则下面发生内存泄漏
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	// ...
//	cout << "delete []" << array << endl;
//	delete[] array; //释放空间
//}
//int main()
//{
//	try{
//		Func();
//	}
//	catch (const char* errmsg){
//		cout << errmsg << endl;
//	}
//	return 0;
//}


// 服务器开发中通常使用的异常继承体系
class Exception //定义一个基类
{
public:
	Exception(const string& errmsg, int id)
		:_errmsg(errmsg)
		, _id(id)
	{}

	virtual string what() const
	{
		return _errmsg;
	}

protected: //至少包含两个成员：errmsg和id

	string _errmsg; //描述是什么样的错误
	int _id; //错误的编号，判断是哪一类错误
};

class SqlException : public Exception
{
public:
	SqlException(const string& errmsg, int id, const string& sql)
		:Exception(errmsg, id)
		, _sql(sql)
	{}

	virtual string what() const
	{
		string str = "SqlException:";
		str += _errmsg;
		str += "->";
		str += _sql;
		return str;
	}

private:
	const string _sql;
};

class HttpServerException : public Exception
{
public:
	//                               错误信息   错误编号          请求类型
	HttpServerException(const string& errmsg, int id, const string& type)
		:Exception(errmsg, id) //先初始化父类成员
		, _type(type) 
	{}

	virtual string what() const
	{
		string str = "HttpServerException:";
		str += _type;
		str += ":";
		str += _errmsg;

		return str;
	}

private:
	const string _type;
};

//---------------------------------------------------------------------------//

void SQLMgr()
{
	// ...
	srand(time(0));
	if (rand() % 7 == 0)
	{
		throw SqlException("权限不足", 100, "select * from name = '张三'");
	}
	// ...
}

void HttpServer()
{
	// ...
	srand(time(0));
	if (rand() % 3 == 0)
	{
		throw HttpServerException("请求资源不存在", 100, "get");
	}
	else if (rand() % 4 == 0)
	{
		throw HttpServerException("权限不足", 101, "post");
	}
	// ...
}

void ServerStart()
{
	while (true)
	{
		this_thread::sleep_for(chrono::seconds(1));

		try// try内部可能会抛异常
		{
			HttpServer();
			SQLMgr();
		}
		catch (const Exception& e)// 这里只用捕获父类对象就可以了
		{
			cout << e.what() << endl;// 多态--> 父类对象/指针调用+完成虚函数重写
			                         // 效果：指向谁调用谁的what
		}
		catch (...)// 若有人未按规范抛异常，则会跳到这里
		{
			cout << "Unkown Exception" << endl;
		}
	}
}

int main()
{
	ServerStart();

	return 0;
}




